﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DiscoveryLogic.Analytics.DataObjects;
using DiscoveryLogic.Analytics.UI.Common.Events;
using DiscoveryLogic.Common.Utilities;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Wpf.Events;
using EntityBase=DiscoveryLogic.Analytics.DataObjects.EntityBase;

namespace DiscoveryLogic.Analytics.Diagrams.GravityGraphs
{
    public class GravityGraphPresenter
    {
        private readonly IEventAggregator _EventAggregator;
        private SubscriptionToken _SubscribPersonEventToken;
        private SubscriptionToken _SubscribPubEventToken;
        private SubscriptionToken _SubscribOrgEventToken;
        private SubscriptionToken _SubscribGrantEventToken;

        private GravityGraphView _View;
        /// <summary></summary>
        public GravityGraphView View
        {
            get
            {
                return this._View;
            }
            set
            {
                this._View = value;
                if (this._View != null)
                {
                    this._View.EntitySelected +=
                        new GravityGraphView.OnEntitySelected(PublishEntitySelectedEvent);
                        
                }
            }
        }

        public GravityGraphPresenter(IEventAggregator eventAggregator)
        {
            this._EventAggregator = eventAggregator;
        }

        #region events 
        private void PublishEntitySelectedEvent(EntityBase entity)
        {
            if (entity != null)
            {
                switch (entity.EntityType)
                {
                    case EntityType.Persons:
                        PersonDO person = (PersonDO)entity;
                        PersonSelectedEvent personSelectedEvent = this._EventAggregator.GetEvent<PersonSelectedEvent>();
                        personSelectedEvent.Publish(person);
                        break;
                    case EntityType.Grants:
                        GrantDO grant = (GrantDO)entity;
                        GrantSelectedEvent grantSelectedEvent = this._EventAggregator.GetEvent<GrantSelectedEvent>();
                        grantSelectedEvent.Publish(grant);
                        break;
                    case EntityType.Organizations:
                        ExternalOrgDO org = (ExternalOrgDO)entity;
                        this._EventAggregator.GetEvent<OrganizationSelectedEvent>().Publish(org);
                        break;
                    case EntityType.Publications:
                        PublicationDO pub = (PublicationDO)entity;
                        this._EventAggregator.GetEvent<PublicationSelectedEvent>().Publish(pub);
                        break;
                }
            }
        }

        public void UpdateViewSelection(EntityBase entity)
        {
            if (entity != null)
            {
                switch (entity.EntityType)
                {
                    case EntityType.Persons:
                        PersonSelectedEvent personSelectedEvent = this._EventAggregator.GetEvent<PersonSelectedEvent>();
                        if (this._SubscribPersonEventToken != null)
                        {
                            personSelectedEvent.Unsubscribe(_SubscribPersonEventToken);
                        }
                        _SubscribPersonEventToken = personSelectedEvent.Subscribe(
                            UpdateViewSelectionHandler, ThreadOption.UIThread, false);
                        break;
                    case EntityType.Grants:
                        GrantSelectedEvent grantSelectedEvent = this._EventAggregator.GetEvent<GrantSelectedEvent>();
                        if (this._SubscribGrantEventToken != null)
                        {
                            grantSelectedEvent.Unsubscribe(_SubscribGrantEventToken);
                        }
                        _SubscribGrantEventToken = grantSelectedEvent.Subscribe(
                            UpdateViewSelectionHandler, ThreadOption.UIThread, false);
                        break;
                    case EntityType.Organizations:
                        OrganizationSelectedEvent organizationSelectedEvent = this._EventAggregator.GetEvent<OrganizationSelectedEvent>();
                        if (this._SubscribOrgEventToken != null)
                        {
                            organizationSelectedEvent.Unsubscribe(_SubscribOrgEventToken);
                        }
                        _SubscribOrgEventToken = organizationSelectedEvent.Subscribe(
                            UpdateViewSelectionHandler, ThreadOption.UIThread, false);
                        break;
                    case EntityType.Publications:
                        PublicationSelectedEvent publicationSelectedEvent = this._EventAggregator.GetEvent<PublicationSelectedEvent>();
                        if (this._SubscribPubEventToken != null)
                        {
                            publicationSelectedEvent.Unsubscribe(_SubscribPubEventToken);
                        }
                        _SubscribPubEventToken = publicationSelectedEvent.Subscribe(
                            UpdateViewSelectionHandler, ThreadOption.UIThread, false);
                        break;
                }

            }
        }

        private void UpdateViewSelectionHandler(PersonDO person)
        {
            this._View.SelectEntity(person);
        }

        private void UpdateViewSelectionHandler(PublicationDO pub)
        {
            this._View.SelectEntity(pub);
        }

        private void UpdateViewSelectionHandler(GrantDO grant)
        {
            this._View.SelectEntity(grant);
        }

        private void UpdateViewSelectionHandler(ExternalOrgDO org)
        {
            this._View.SelectEntity(org);
        }
        #endregion 
    }
}
